Skip to content
Built 26/04/17 09:08commit f8ff6f9

中文 | English

Image

在《The Shorthand Guide to Everything Claude Code》中,我介绍了基础设置:skills 和 commands、hooks、subagents、MCPs、plugins,以及构成高效 Claude Code 工作流骨架的配置模式。那是一篇设置指南,也是基础设施层。

1 月 17 日

这篇长文指南讨论的是那些将高效会话与低效会话区分开的技术。如果你还没读过 Shorthand Guide**,**先回去把你的配置设置好。接下来的内容默认你已经把 skills、agents、hooks 和 MCPs 配置并运行起来了。

这里的主题包括:token 经济学、记忆持久化、验证模式、并行化策略,以及构建可复用工作流所带来的复利效应。这些是我在 10 个多月的日常使用中打磨出来的模式,它们决定了你是在第一个小时内就被上下文腐化困扰,还是能够连续数小时保持高效会话。

shorthand 和 longform 两篇文章中涵盖的所有内容都可以在 github 上这里找到:everything-claude-code

上下文与记忆管理

为了在不同会话之间共享记忆,最好的办法是使用一个 skill 或 command:它能够总结并检查进展,然后将内容保存到你 .claude 文件夹中的 .tmp 文件里,并在整个会话结束前持续追加。第二天它就可以把这个作为上下文,接着你上次停下来的地方继续。为每次会话创建一个新文件,这样就不会把旧上下文污染到新的工作中。最终你会得到一个装满这些会话日志的大文件夹,只需要把它备份到有意义的地方,或者清理掉那些你不需要的会话记录。

Claude 会创建一个总结当前状态的文件。检查它,必要时要求修改,然后重新开始。对于新的对话,你只需要提供这个文件路径即可。这个方法在你触及上下文限制、需要继续复杂工作时尤其有用。这些文件应当包含:哪些方法有效(并且有证据验证)、哪些尝试过的方法无效、哪些方法尚未尝试,以及还剩下哪些工作要做。

Image

会话存储示例 -> https://github.com/affaan-m/everything-claude-code/tree/main/examples/sessions

有策略地清理上下文:

一旦你已经制定好计划并清理了上下文(现在在 claude code 的 plan mode 里这是默认选项),你就可以按照计划开展工作。当你积累了大量与执行已无关的探索性上下文时,这会很有用。对于策略性的 compact,关闭自动 compact。在逻辑间隔点手动 compact,或者创建一个 skill 来替你这么做,或在满足某些定义好的条件时给出建议。

Strategic Compact Skill (直接链接):

(为便于快速参考,嵌入如下)

bash
#!/bin/bash
# Strategic Compact Suggester
# Runs on PreToolUse to suggest manual compaction at logical intervals
#
# Why manual over auto-compact:
# - Auto-compact happens at arbitrary points, often mid-task
# - Strategic compacting preserves context through logical phases
# - Compact after exploration, before execution
# - Compact after completing a milestone, before starting next

COUNTER_FILE="/tmp/claude-tool-count-$$"
THRESHOLD=${COMPACT_THRESHOLD:-50}

# Initialize or increment counter
if [ -f "$COUNTER_FILE" ]; then
  count=$(cat "$COUNTER_FILE")
  count=$((count + 1))
  echo "$count" > "$COUNTER_FILE"
else
  echo "1" > "$COUNTER_FILE"
  count=1
fi

# Suggest compact after threshold tool calls
if [ "$count" -eq "$THRESHOLD" ]; then
  echo "[StrategicCompact] $THRESHOLD tool calls reached - consider /compact if transitioning phases" >&2
fi

把它挂到 Edit/Write 操作的 PreToolUse 上;当你积累了足够多、可能适合 compact 的上下文时,它会提醒你。

进阶:动态系统提示注入

我学到并正在试运行的一种模式是:不要只把所有内容都放进 CLAUDE.md(用户作用域)或 .claude/rules/(项目作用域)里并让它在每个会话中加载,而是使用 CLI flags 动态注入上下文。

bash
claude --system-prompt "$(cat memory.md)"

这让你可以更精细地控制在什么时间加载什么上下文。你可以根据当前在做的工作,在每个会话中注入不同的上下文。

为什么这和 @ 文件引用不同:

当你使用 [@memory](https://x.com/@memory).md 或者把某些内容放进 .claude/rules/ 时,Claude 会在对话过程中通过 Read tool 去读取它,它会作为工具输出被引入。而当你使用 --system-prompt 时,内容会在对话开始前被注入到真正的 system prompt 中。

差异在于指令层级。System prompt 的内容权重高于 user messages,而 user messages 又高于 tool results。对大多数日常工作来说,这个差异影响不大。但对于严格的行为规则、项目特定约束,或者那些你绝对需要 Claude 优先考虑的上下文,system prompt 注入能够确保它被赋予恰当的权重。

实用设置:

一种有效的做法是:用 .claude/rules/ 来放置你的基础项目规则,然后为特定场景准备 CLI aliases,以便在不同上下文之间切换:

bash
# Daily development
alias claude-dev='claude --system-prompt "$(cat ~/.claude/contexts/dev.md)"'

# PR review mode
alias claude-review='claude --system-prompt "$(cat ~/.claude/contexts/review.md)"'

# Research/exploration mode
alias claude-research='claude --system-prompt "$(cat ~/.claude/contexts/research.md)"'

System Prompt Context Example Files (直接链接):

  • dev.md 聚焦于实现
  • review.md 聚焦于代码质量/安全性
  • research.md 聚焦于行动前的探索

再次说明,对于大多数情况,使用 .claude/rules/context1.md 和直接把 context1.md 追加到你的 system prompt 之间的差别很小。CLI 方式更快(无工具调用)、更可靠(系统级权威)、并且略微更节省 token。但这只是一个小优化,对很多人来说,它带来的额外负担可能大于收益。

进阶:记忆持久化 Hooks

有一些 hooks 大多数人并不知道,或者即使知道也没有真正利用起来,而它们对记忆非常有帮助:

plaintext
SESSION 1                              SESSION 2
─────────                              ─────────

[Start]                                [Start]
   │                                      │
   ▼                                      ▼
┌──────────────┐                    ┌──────────────┐
│ SessionStart │ ◄─── reads ─────── │ SessionStart │◄── loads previous
│    Hook      │     nothing yet    │    Hook      │    context
└──────┬───────┘                    └──────┬───────┘
       │                                   │
       ▼                                   ▼
   [Working]                           [Working]
       │                               (informed)
       ▼                                   │
┌──────────────┐                           ▼
│  PreCompact  │──► saves state       [Continue...]
│    Hook      │    before summary
└──────┬───────┘


   [Compacted]


┌──────────────┐
│  Stop Hook   │──► persists to ──────────►
│ (session-end)│    ~/.claude/sessions/
└──────────────┘
  • PreCompact Hook: 在上下文压缩发生之前,把重要状态保存到文件中
  • SessionComplete Hook: 在会话结束时,把学习成果持久化到文件中
  • SessionStart Hook: 在新会话开始时,自动加载先前的上下文

Memory Persistant Hooks (直接链接):

(为便于快速参考,嵌入如下)

json
{
  "hooks": {
    "PreCompact": [{
      "matcher": "*",
      "hooks": [{
        "type": "command",
        "command": "~/.claude/hooks/memory-persistence/pre-compact.sh"
      }]
    }],
    "SessionStart": [{
      "matcher": "*",
      "hooks": [{
        "type": "command",
        "command": "~/.claude/hooks/memory-persistence/session-start.sh"
      }]
    }],
    "Stop": [{
      "matcher": "*",
      "hooks": [{
        "type": "command",
        "command": "~/.claude/hooks/memory-persistence/session-end.sh"
      }]
    }]
  }
}

这些脚本的作用:

  • pre-compact.sh 记录压缩事件,用压缩时间戳更新当前活跃的会话文件
  • session-start.sh 检查最近的会话文件(过去 7 天),提示可用的上下文和已学习的技能
  • session-end.sh 使用模板创建/更新每日会话文件,跟踪开始/结束时间

把它们串联起来,你就可以在不同会话之间持续保留记忆,而无需手动干预。这建立在文章 1 中介绍的 hook 类型(PreToolUse、PostToolUse、Stop)之上,但它专门针对会话生命周期。

持续学习 / 记忆

我们讨论过以更新 codemaps 形式进行持续记忆更新,但这也适用于其他事情,比如从错误中学习。如果你不得不重复多次发出同一个提示,而 Claude 又遇到了同样的问题,或者给出了你已经听过的回答,那么这对你就适用。

很可能你需要再发第二个提示来“重新引导”并校准 Claude 的方向感。这适用于任何类似场景,这些模式都必须追加到 skills 中。

现在你可以直接告诉 Claude 记住它,或者把它添加到你的 rules 中来自动实现;你也可以准备一个专门做这件事的 skill。

问题: 浪费 token,浪费上下文,浪费时间;当 Claude 做了你明明在上一次会话里就已经告诉它不要做的事时,你的皮质醇飙升,沮丧地冲着 claude 大喊。

解决方案: 当 Claude Code 发现某些并不平凡的东西时,比如一种调试技术、一个变通方案、某种项目特定模式,它就会把这些知识保存为新的 skill。下次再遇到类似问题时,这个 skill 就会被自动加载。

Continuous Learning Skill (直接链接):

为什么我使用的是 Stop hook 而不是 UserPromptSubmit?因为 UserPromptSubmit 会在你发送的每一条消息上运行,这会带来很大的开销,为每个提示增加延迟,而且坦白说,对这个用途来说太过头了。Stop 只会在会话结束时运行一次,足够轻量,不会拖慢你在会话中的节奏,而且它评估的是完整会话,而不是零碎片段。

安装:

bash
# Clone to skills folder
git clone https://github.com/affaan-m/everything-claude-code.git ~/.claude/skills/everything-claude-code

# Or just grab the continuous-learning skill
mkdir -p ~/.claude/skills/continuous-learning
curl -sL https://raw.githubusercontent.com/affaan-m/everything-claude-code/main/skills/continuous-learning/evaluate-session.sh > ~/.claude/skills/continuous-learning/evaluate-session.sh
chmod +x ~/.claude/skills/continuous-learning/evaluate-session.sh

Hook Configuration (直接链接):

json
{
  "hooks": {
    "Stop": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/skills/continuous-learning/evaluate-session.sh"
          }
        ]
      }
    ]
  }
}

这会使用 Stop hook 在每次 prompt 上运行一个激活脚本,以评估该会话中是否存在值得提取的知识。该 skill 也可以通过语义匹配被激活,但 hook 可以确保评估始终发生。

Stop hook 会在你的会话结束时触发。脚本会分析整个会话,寻找值得提取的模式(错误解决方式、调试技巧、变通方案、项目特定模式等),并将它们保存为可复用的 skills,位置在 ~/.claude/skills/learned/

使用 /learn 手动提取:

你不必等到会话结束。这个仓库还包含一个 /learn command,你可以在会话中途、刚刚解决了某个不平凡问题时运行它。它会提示你立刻提取这个模式,起草一个 skill 文件,并在保存前请求你确认。见这里

会话日志模式:

这个 skill 期望会话日志存储在 .tmp 文件中。模式是:~/.claude/sessions/YYYY-MM-DD-topic.tmp,即每个会话一个文件,其中包含当前状态、已完成事项、阻塞项、关键决策,以及下一次会话所需的上下文。示例会话文件可在仓库中的 examples/sessions/ 找到。

其他自我改进型记忆模式:

@RLanceMartin 的一种做法,是通过反思会话日志来提炼用户偏好,本质上是在构建一本关于“什么有效、什么无效”的“日记”。每次会话之后,一个反思 agent 会提取哪些做得好、哪些失败了、你做了哪些修正。这些学习结果会更新一个记忆文件,并在后续会话中加载。

@alexhillman 的另一种做法,则是系统每隔 15 分钟主动提出改进建议,而不是等你自己发现模式。Agent 会回顾最近的交互,提出记忆更新建议,你来批准或拒绝。随着时间推移,它会从你的批准模式中学习。## Token 优化

我从价格敏感型用户那里收到了很多问题,或者说那些作为重度用户经常遇到限制问题的人。在 token 优化这件事上,你可以用一些技巧。

主要策略:子代理架构

主要是在优化你使用的工具,以及优化子代理架构,目标是为任务委派足够胜任且尽可能便宜的模型,以减少浪费。这里你有几种选择,你可以通过反复试验并在过程中调整。等你弄清楚各自适合什么之后,你就可以判断哪些任务委派给 Haiku,哪些委派给 Sonnet,哪些委派给 Opus。

基准测试方法(更复杂一些):

另一种更复杂一点的方法是,你可以让 Claude 搭建一个基准测试环境,准备一个目标和任务定义明确、计划也明确的仓库。在每个 git worktree 中,让所有子代理都使用同一个模型。随着任务完成进行记录,最好记录在你的计划和任务中。你需要至少使用每个子代理一次。

当你完成一整轮,并且 Claude 计划中的任务都被勾选完成后,停止并审查进度。你可以通过比较 diff、创建在所有 worktree 中都统一的单元测试、集成测试和 E2E 测试来做到这一点。这样你就能根据通过案例与失败案例得到一个数值基准。如果所有模型都全部通过了,你就需要增加更多测试边缘情况,或者提高测试复杂度。这件事值不值得做,取决于这件事对你到底有多重要。

模型选择速查:

Image

各种常见任务上的子代理假设性配置,以及做出这些选择的原因

90% 的编码任务默认使用 Sonnet。当第一次尝试失败、任务跨越 5 个以上文件、涉及架构决策,或是安全关键代码时,升级到 Opus。当任务是重复性的、指令非常明确,或者在多代理设置中作为“worker”使用时,降级到 Haiku。坦白说,Sonnet 4.5 目前处在一个比较尴尬的位置,价格是每百万输入 token 3 美元、每百万输出 token 15 美元。相较于 Opus,成本节省大约是 66.7%,绝对数值上这确实是不错的节省,但相对来说对大多数人而言更多是无关紧要。Haiku 和 Opus 的组合最合理,因为 Haiku 与 Opus 之间有 5 倍的成本差,而和 Sonnet 相比价格差仅为 1.67 倍。

Image

来源:https://platform.claude.com/docs/en/about-claude/pricing

在你的代理定义中,指定模型:

yaml
---
name: quick-search
description: Fast file search
tools: Glob, Grep
model: haiku # Cheap and fast
---

工具级优化:

想想 Claude 最常调用的是哪些工具。例如,把 grep 换成 mgrep,在各种任务上,相比传统的 grep 或 ripgrep,平均来看能有效减少大约一半的 token,这也是 Claude 默认使用的工具。

Image

来源:https://github.com/mixedbread-ai/mgrep/blob/main/README.md

后台进程:

在适用的情况下,如果你不需要 Claude 处理全部输出,也不需要它直接实时流式接收输出,就把后台进程放到 Claude 外部运行。这可以很容易通过 tmux 实现(参见 Shorthand GuideTmux Commands Reference (Direct Link))。把终端输出拿过来之后,要么做摘要,要么只复制你需要的部分。这能节省大量输入 token,而大部分成本就来自这里。Opus 4.5 的输入是每百万 token 5 美元,输出是每百万 token 25 美元。

模块化代码库的收益:

拥有一个更模块化的代码库,带有可复用的工具、函数、hooks 等,并让主文件保持在数百行而不是数千行,这对 token 优化成本和一次性把任务做对都有帮助,而这两者本身是相关的。如果你不得不多次提示 Claude,你就在不断消耗 token,特别是在它反复读取超长文件时。你会注意到,为了读完整个文件,它不得不发起很多工具调用。在中间阶段,它会告诉你文件很长,并将继续读取。在这个过程中某个地方,Claude 可能会丢失一些信息。此外,停下来重新读取还会额外消耗 token。通过更模块化的代码库可以避免这些问题。示例如下 ->

plaintext
root/
├── docs/                   # 全局文档
├── scripts/                # CI/CD 和构建脚本
├── src/
│   ├── apps/               # 入口点(API、CLI、Workers)
│   │   ├── api-gateway/    # 将请求路由到各模块
│   │   └── cron-jobs/      
│   │
│   ├── modules/            # 系统核心
│   │   ├── ordering/       # 自包含的“Ordering”模块
│   │   │   ├── api/        # 面向其他模块的公共接口
│   │   │   ├── domain/     # 业务逻辑与实体(纯)
│   │   │   ├── infrastructure/ # DB、外部客户端、仓储
│   │   │   ├── use-cases/  # 应用逻辑(编排)
│   │   │   └── tests/      # 单元测试和集成测试
│   │   │
│   │   ├── catalog/        # 自包含的“Catalog”模块
│   │   │   ├── domain/
│   │   │   └── ...
│   │   │
│   │   └── identity/       # 自包含的“Auth/User”模块
│   │       ├── domain/
│   │       └── ...
│   │
│   ├── shared/             # EVERY 模块都会使用的代码
│   │   ├── kernel/         # 基础类(Entity、ValueObject)
│   │   ├── events/         # 全局事件总线定义
│   │   └── utils/          # 深度通用辅助函数
│   │
│   └── main.ts             # 应用启动入口
├── tests/                  # 端到端(E2E)全局测试
├── package.json
└── README.md

精简代码库 = 更便宜的 token:

这可能很明显,但你的代码库越精简,token 成本就越低。关键在于使用 skills 持续清理代码库,通过配合 skills 和命令进行重构来识别死代码。另外在某些阶段,我喜欢通读并快速浏览整个代码库,寻找那些显眼的或看起来重复的部分,手动拼接出相关上下文,然后把这些上下文和重构 skill、死代码 skill 一起交给 Claude。

精简系统提示词(高级):

对于真正关心成本的人来说:Claude Code 的系统提示词大约占用 ~18k tokens(约为 200k 上下文的 9%)。通过打补丁可以将其降到 ~10k tokens,节省约 7,300 tokens(静态开销的 41%)。如果你想走这条路,可以看看 YK 的 system-prompt-patches,不过我个人不这么做。

验证循环与评测

评测与 harness 调优,这取决于项目,但你通常会想要某种形式的可观测性和标准化。

可观测性方法:

一种方式是使用 tmux 进程,在每次 skill 被触发时,挂钩追踪思考流和输出。另一种方式是设置一个 PostToolUse hook,记录 Claude 具体执行了什么,以及确切的变更和输出是什么。

基准测试工作流:

把它和在没有 skill 的情况下请求同样的事情进行对比,并检查输出差异,以基准化相对性能:

plaintext
[同一任务]

            ┌────────────┴────────────┐
            ▼                         ▼
    ┌───────────────┐         ┌───────────────┐
    │  Worktree A   │         │  Worktree B   │
    │   使用 skill  │         │ 不使用 skill  │
    └───────┬───────┘         └───────┬───────┘
            │                         │
            ▼                         ▼
       [输出 A]                  [输出 B]
            │                         │
            └──────────┬──────────────┘

                  [git diff]


              ┌────────────────┐
              │ 比较日志、     │
              │ token 使用量、 │
              │ 输出质量       │
              └────────────────┘

分叉这段对话,在其中一个新 worktree 里不使用 skill,最后拉出 diff,看记录了什么。这也和“持续学习与记忆”那一节有关。

评测模式类型:

更高级的评测和循环协议就在这里展开。它们分为基于检查点的评测,以及基于 RL 任务的持续评测。

plaintext
基于检查点                              持续评测
───────────                             ────────

  [任务 1]                                 [工作]
     │                                        │
     ▼                                        ▼
  ┌─────────┐                            ┌─────────┐
  │ 检查点  │◄── 验证                    │ 计时器/ │
  │   #1    │    标准                    │ 变更    │
  └────┬────┘                            └────┬────┘
       │ 通过?                                │
   ┌───┴───┐                                  ▼
   │       │                            ┌──────────┐
  是      否 ──► 修复 ──┐               │运行测试  │
   │              │    │               │ + Lint   │
   ▼              └────┘               └────┬─────┘
 [任务 2]                                    │
    │                                   ┌────┴────┐
    ▼                                   │         │
 ┌─────────┐                           通过      失败
 │ 检查点  │                            │         │
 │   #2    │                            ▼         ▼
 └────┬────┘                         [继续]   [停止并修复]
      │                                           │
     ...                                     └────┘

最适合:线性工作流                     最适合:长时会话
具有清晰里程碑                        探索式重构

基于检查点的评测:

  • 在你的工作流中设置明确的检查点
  • 在每个检查点按定义好的标准进行验证
  • 如果验证失败,Claude 必须先修复再继续
  • 适合具有明确里程碑的线性工作流

持续评测:

  • 每隔 N 分钟或在重大变更后运行
  • 全量测试套件、构建状态、lint
  • 立即报告回归
  • 先停止并修复,再继续
  • 适合长时间运行的会话

决定因素在于你的工作性质。基于检查点的方式适合具有清晰阶段的功能实现。持续评测适合探索式重构或维护工作,因为这类工作没有清晰的里程碑。

我会说,只要有一定人工干预,这种验证方式足以避免大多数技术债。让 Claude 在完成任务后通过运行 skills 和 PostToolUse hooks 来做验证,会对此有所帮助。持续更新 codemap 也有帮助,因为它会记录变更日志以及 codemap 随时间如何演变,成为 repo 本身之外的事实来源。有了严格规则,Claude 也会避免随意创建一堆 .md 文件造成混乱,也能避免为相似代码创建重复文件,或者留下大片死代码荒地。

Grader Types (From Anthropic - Direct Link):

基于代码的评分器: 字符串匹配、二元测试、静态分析、结果验证。快速、便宜、客观,但对有效变体很脆弱。

基于模型的评分器: 量表评分、自然语言断言、两两比较。灵活并能处理细微差别,但非确定性且成本更高。

人工评分器: SME 审查、众包判断、抽样点检。质量是黄金标准,但成本高且速度慢。

关键指标:

plaintext
pass@k: k 次尝试中至少有 ONE 次成功
        ┌─────────────────────────────────────┐
        │  k=1: 70%  k=3: 91%  k=5: 97%      │
        │  更高的 k = 更高的成功概率         │
        └─────────────────────────────────────┘

pass^k: k 次尝试中 ALL 都必须成功
        ┌─────────────────────────────────────┐
        │  k=1: 70%  k=3: 34%  k=5: 17%      │
        │  更高的 k = 更难(更强调一致性)   │
        └─────────────────────────────────────┘

当你只需要它能工作,并且任何可验证反馈都足够时,使用 pass@k。当一致性至关重要,并且你需要接近确定性的输出一致性(从结果/质量/风格的角度)时,使用 pass^k

构建评测路线图(来自同一篇 Anthropic 指南):

  1. 尽早开始,从真实失败案例中挑选 20-50 个简单任务
  2. 将用户报告的失败转化为测试用例
  3. 编写无歧义任务,两个专家应当得出相同结论
  4. 构建平衡的问题集,同时测试行为应该发生和不应该发生的情况
  5. 构建稳健的 harness,每次试验都从干净环境开始
  6. 评估代理产出的结果,而不是它采取的路径
  7. 阅读大量试验的转录记录
  8. 监控饱和度,100% 通过率意味着需要增加更多测试## 并行化

在多 Claude 终端设置中 fork 对话时,务必确保 fork 和原始对话中的操作范围定义清晰。代码改动应尽量减少重叠。选择彼此正交的任务,以防止相互干扰的可能性。

我偏好的模式:

就我个人而言,我更喜欢让主聊天处理代码改动,而我创建的 fork 则用于回答我对代码库及其当前状态的疑问,或者对外部服务进行研究,例如拉取文档、在 GitHub 上搜索有助于当前任务的适用开源仓库,或进行其他有帮助的通用研究。

关于任意终端数量:

Boris @bcherny(创造 claude code 的传奇人物)对并行化有一些建议,其中有些我同意,有些我不同意。他曾建议诸如本地运行 5 个 Claude 实例,再加上上游 5 个。我不建议这样设定任意数量的终端。增加一个终端、增加一个实例,都应该出于真正的必要性和明确目的。如果你能用脚本完成那个任务,就用脚本。如果你可以留在主聊天里,并让 Claude 在 tmux 中启动一个实例并以那种方式在另一个终端中流式输出,那就那样做。

1 月 3 日

1/ 我在终端里并行运行 5 个 Claude。我给标签页编号 1-5,并使用系统通知来知道何时某个 Claude 需要输入 https://code.claude.com/docs/en/terminal-config#iterm-2-system-notifications…

你真正的目标应该是:用最低可行程度的并行化,完成尽可能多的事情。

对于大多数新手来说,我甚至会建议在你真正掌握如何运行单个实例并在其中管理一切之前,先远离并行化。我不是在主张束缚自己,而是在说要谨慎。大多数时候,即便是我,也通常总共只会用 4 个左右的终端。我发现通常只开 2 或 3 个 Claude 实例,就能完成大多数事情。

在扩展实例时:

如果你开始扩展实例数量,并且多个 Claude 实例正在处理彼此重叠的代码,那么务必要使用 git worktree,并为每个实例制定定义非常明确的计划。此外,为了在恢复会话时不至于混淆或迷失,不清楚哪个 git worktree 是做什么的(除了 tree 的名字之外),请使用 /rename <name here> 给所有聊天命名。

用于并行实例的 Git Worktree:

bash
# 为并行工作创建 worktree
git worktree add ../project-feature-a feature-a
git worktree add ../project-feature-b feature-b
git worktree add ../project-refactor refactor-branch

# 每个 worktree 各自运行一个 Claude 实例
cd ../project-feature-a && claude

好处:

  • 实例之间不会产生 git 冲突
  • 每个实例都有干净的工作目录
  • 易于比较输出
  • 可以对同一任务的不同方案进行基准测试

级联方法:

运行多个 Claude Code 实例时,使用“级联”模式进行组织:

  • 在右侧新标签页中打开新任务
  • 从左到右扫一遍,从最旧到最新
  • 保持一致的方向流
  • 根据需要检查特定任务
  • 一次最多专注 3-4 个任务,超过这个数量后,心理负担增长速度会快于生产力提升

基础工作

刚开始时,实际的基础非常重要。这一点本应显而易见,但随着代码库复杂度和规模的增加,技术债务也会增加。管理它极其重要,而且如果你遵循一些规则,也并没有那么难。除了要为手头项目有效设置 Claude(参见简写指南)之外。

双实例启动模式:

就我自己的工作流管理而言(不是必须,但很有帮助),我喜欢在一个空仓库里打开 2 个 Claude 实例开始工作。

实例 1:脚手架代理

  • 负责铺设脚手架和基础工作
  • 创建项目结构
  • 设置配置(CLAUDE.md、rules、agents,以及简写指南中的所有内容)
  • 建立约定
  • 搭好骨架

实例 2:深度研究代理

  • 连接你的所有服务、网页搜索等
  • 创建详细的 PRD
  • 创建架构 mermaid 图
  • 汇编带有真实文档实际摘录的参考资料

Image

起始设置:左侧终端用于编码,右侧终端用于提问,使用 /rename 和 /fork。

开始时你最少需要的东西就足够了,这样比起每次都用 Context7,或者喂给它链接让它去抓取,或者使用 Firecrawl MCP 站点,要更快。只有当你已经深陷某件事情,而 Claude 明显写错语法、使用过时函数或端点时,那些方式才有用。

llms.txt 模式:

如果可用,当你到达某个文档页面后,可以通过在其后加上 `/llms.txt`,在许多文档参考中找到一个 llms.txt。这里有一个例子:https://www.helius.dev/docs/llms.txt

这会给你一个干净的、为 LLM 优化过的文档版本,你可以直接提供给 Claude。

理念:构建可复用模式

来自 @omarsar0 的一个见解我完全赞同:“早期,我花时间构建可复用的工作流/模式。构建起来很繁琐,但随着模型和代理 harness 的改进,这产生了极强的复利效应。”

值得投入的方向:

  • Subagents(简写指南)
  • Skills(简写指南)
  • Commands(简写指南)
  • 规划模式
  • MCP 工具(简写指南)
  • 上下文工程模式

为什么会产生复利(@omarsar0): “最棒的是,所有这些工作流都可以迁移到其他代理上,比如 Codex。” 一旦构建完成,它们就能跨模型升级继续工作。对模式的投入 > 对特定模型技巧的投入。## Agent 与子 Agent 的最佳实践

在速记指南中,我列出了子 agent 结构,如 planner、architect、tdd-guide、code-reviewer 等。在这一部分,我们关注编排与执行层。

子 Agent 的上下文问题:

子 agent 的存在是为了通过返回摘要而不是倾倒全部内容来节省上下文。但编排器拥有子 agent 缺少的语义上下文。子 agent 只知道字面查询,不知道请求背后的 PURPOSE/REASONING。摘要往往会遗漏关键细节。

来自 @PerceptualPeak 的类比:“你的老板让你去开会,并要求你回来做个总结。你回来后给他做了汇报。十有八九,他还会有后续问题。你的总结不会包含他需要的全部内容,因为你没有他拥有的那些隐含上下文。”

迭代式检索模式:

plaintext
┌─────────────────┐
│    编排器       │
│  (拥有上下文) │
└────────┬────────┘
         │ 携带查询 + 目标进行分派

┌─────────────────┐
│    子 Agent     │
│ (缺少上下文)  │
└────────┬────────┘
         │ 返回摘要

┌─────────────────┐      ┌─────────────┐
│     评估        │─否──►│   后续问题  │
│   是否充分?    │      │             │
└────────┬────────┘      └──────┬──────┘
         │ 是                   │
         ▼                      │ 子 agent
      [接受]               回源获取答案

         ◄──────────────────────┘
              (最多 3 轮循环)

要解决这个问题,让编排器:

  • 评估每一次子 agent 的返回结果
  • 在接受结果前提出后续问题
  • 子 agent 返回源头,获取答案,再返回
  • 循环直到足够充分(最多 3 轮,以防无限循环)

传递目标上下文,而不仅仅是查询。 在分派子 agent 时,同时包含具体查询 AND 更广泛的目标。这有助于子 agent 判断哪些内容应优先纳入摘要。

模式:按顺序阶段推进的编排器

markdown
阶段 1:RESEARCH(使用 Explore agent)

- 收集上下文
- 识别模式
- 输出:research-summary.md

阶段 2:PLAN(使用 planner agent)

- 阅读 research-summary.md
- 制定实现计划
- 输出:plan.md

阶段 3:IMPLEMENT(使用 tdd-guide agent)

- 阅读 plan.md
- 先写测试
- 实现代码
- 输出:代码改动

阶段 4:REVIEW(使用 code-reviewer agent)

- 审查所有改动
- 输出:review-comments.md

阶段 5:VERIFY(必要时使用 build-error-resolver)

- 运行测试
- 修复问题
- 输出:完成,或回到前面循环

关键规则:

  1. 每个 agent 获得 ONE 个清晰输入,并产生 ONE 个清晰输出
  2. 输出会成为下一阶段的输入
  3. 永远不要跳过阶段,每个阶段都增加价值
  4. 在 agent 之间使用 `/clear` 以保持上下文清爽
  5. 将中间输出存储到文件中(不只是存在记忆里)

Agent 抽象分级榜(来自 @menhguin):

Tier 1:直接增益(容易使用)

  • Subagents - 用于防止上下文腐化和临时专项化的直接增益。相比 multi-agent 只有一半效用,但复杂度低得多
  • Metaprompting - “我花 3 分钟写 prompt,来完成一个 20 分钟的任务。” 这是直接增益,能提升稳定性并校验假设是否合理
  • 一开始就向用户问更多问题 - 通常也是一种增益,尽管你需要在 plan 模式中回答问题

Tier 2:技能门槛高(更难用好)

  • 长时间运行的 agents - 需要理解 15 分钟任务、1.5 小时任务和 4 小时任务的形态与权衡。需要一些调试,而且显然是非常漫长的试错过程
  • 并行 multi-agent - 方差非常高,只对高度复杂 OR 切分良好的任务有用。“如果两个任务各花 10 分钟,而你还要花不定量时间写 prompt,或者更糟,合并改动,那就是适得其反”
  • 基于角色的 multi-agent - “模型演化太快了,除非套利空间极高,否则很难依赖硬编码启发式规则。” 很难测试
  • 计算机使用 agents - 这是非常早期的范式,需要大量驯服。“你是在让模型去做一年前它们肯定原本根本不是为了做的事情”

要点是:从 Tier 1 模式开始。只有在你掌握了基础,并且确实有需要时,才升级到 Tier 2。

技巧与窍门

有些 MCP 是可替代的,并且会释放你的上下文窗口

方法如下。

对于版本控制(GitHub)、数据库(Supabase)、部署(Vercel、Railway)等 MCP,这些平台中的大多数本来就已经有成熟的 CLI,而 MCP 本质上只是对它们的封装。MCP 是个不错的封装,但它是有代价的。

如果你想让 CLI 在不实际使用 MCP 的情况下更像一个 MCP(同时避免其带来的上下文窗口缩减),可以考虑把功能打包进 skills 和 commands。把 MCP 暴露出来那些方便易用的工具剥离出来,变成命令。

例如:与其始终加载 GitHub MCP,不如创建一个 `/gh-pr` 命令,用你偏好的选项去封装 `gh pr create`。与其让 Supabase MCP 吃掉上下文,不如创建直接使用 Supabase CLI 的 skills。功能是一样的,便利性也相近,但你的上下文窗口就释放出来做真正的工作了。

这也和最近别人问我的一些问题有关。自从我发布原始文章后的这几天里,Boris 和 Claude Code 团队在内存管理和优化方面取得了很多进展,主要是通过对 MCP 的懒加载,从而不再在一开始就占用你的窗口。以前我会建议,只要能做,就把 MCP 转成 skills,把执行 MCP 的能力通过两种方式之一转移出去:要么在需要时再启用它(不太理想,因为你需要离开并恢复会话),要么编写使用 MCP 对应 CLI 的 skills(如果存在对应 CLI),让 skill 作为外层封装,本质上让它充当一种伪 MCP。

有了 lazy loading,上下文窗口问题基本解决了。但 token 使用量和成本并没有以同样方式得到解决。CLI + skills 的方式仍然是一种 token 优化方法,而且其效果可能与使用 MCP 相当或接近。此外,你还可以通过 CLI 而不是在上下文中执行 MCP 操作,这会显著减少 token 使用量,尤其适用于数据库查询或部署这类重量级 MCP 操作。

视频?

正如你所建议的,我在想,这篇文章加上我收到的其他一些问题,也许值得配一个视频,一起讲解这些内容。

制作一个端到端项目,结合两篇文章中的策略:

  • 使用速记指南中的配置完成完整项目搭建
  • 在实战中演示这篇长文指南中的高级技巧
  • 实时 token 优化
  • 实践中的验证循环
  • 跨会话的内存管理
  • 双实例启动模式
  • 使用 git worktree 的并行工作流
  • 实际工作流的截图与录屏

我看看能做些什么。

参考资料